package com.zycfc.zsf.boot.redis;

import com.zycfc.zsf.boot.redis.autoconfigure.*;
import com.zycfc.zsf.boot.serializer.*;
import com.zycfc.zsf.boot.redis.command.*;
import com.zycfc.zsf.boot.util.net.*;
import com.zycfc.zsf.boot.redis.constant.*;
import java.io.*;
import javax.annotation.*;
import com.zycfc.zsf.boot.util.time.*;
import com.zycfc.zsf.boot.localcache.cache.*;
import java.util.concurrent.*;
import com.zycfc.zsf.boot.redis.domain.*;
import com.zycfc.zsf.boot.redis.enums.*;
import com.zycfc.zsf.boot.redis.util.*;
import com.zycfc.zsf.boot.util.json.*;
import redis.clients.jedis.*;
import org.springframework.data.redis.core.*;
import java.util.*;
import org.slf4j.*;

public class RedisOperater implements IRedisOperater
{
    private static final Logger log;
    private static final String REDIS_EXE_STS_S = "S";
    private static final String REDIS_EXE_STS_F = "F";
    protected final RedisProperties config;
    protected final ISerializer serializer;
    private final RedisBinaryCommand redisCommand;
    private String appName;
    private String ip;
    private boolean notProdEnv;
    
    public RedisOperater(final RedisProperties config, final ISerializer serializer, final RedisBinaryCommand redisCommand) {
        this.config = config;
        this.serializer = serializer;
        this.redisCommand = redisCommand;
    }
    
    public RedisOperater(final RedisProperties config, final ISerializer serializer, final RedisBinaryCommand redisCommand, final String appName) {
        this.config = config;
        this.serializer = serializer;
        this.redisCommand = redisCommand;
        this.appName = appName;
        this.ip = NetUtils.getLocalHostIp();
    }
    
    public RedisOperater(final RedisProperties config, final ISerializer serializer, final RedisBinaryCommand redisCommand, final String appName, final boolean notProdEnv) {
        this.config = config;
        this.serializer = serializer;
        this.redisCommand = redisCommand;
        this.appName = appName;
        this.ip = NetUtils.getLocalHostIp();
        this.notProdEnv = notProdEnv;
    }
    
    @PostConstruct
    void init() {
        try {
            if (OSUtils.isWin() || OSUtils.isMac()) {
                RedisConstant.REDIS_FILE_DIR = RedisConstant.class.getResource("/").getPath();
                RedisConstant.REDIS_FILE_PATH = RedisConstant.REDIS_FILE_DIR + "/redis.txt";
            }
            final File fileDir = new File(RedisConstant.REDIS_FILE_DIR);
            final File redisFile = new File(RedisConstant.REDIS_FILE_PATH);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }
            if (!redisFile.exists()) {
                redisFile.createNewFile();
            }
        }
        catch (Throwable e) {
            RedisOperater.log.error("\u521d\u59cb\u5316\u521b\u5efaredis\u672c\u5730\u5b58\u50a8\u6587\u4ef6Exception:", e);
        }
    }
    
    @Override
    public Boolean exists(final String key) {
        return this.exists(key, false);
    }
    
    @Override
    public Boolean exists(final String key, final boolean isFullKey) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.exists, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> jedis.exists(k), isFullKey, redisMonitor);
    }
    
    @Override
    public <T> void set(final String key, final T value) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.set, this, this.appName, this.notProdEnv);
        String realKey;
        CopyOnWriteArrayList<RedisCallInf> list;
        String cacheGroup;
        String cacheKey;
        Object obj;
        final byte[] valueBytes;
        long beginTm;
        String result;
        long endTm;
        long callDur;
        int valSize;
        final String res = this.doCommand(key, (k, jedis) -> {
            realKey = null;
            list = null;
            cacheGroup = null;
            cacheKey = null;
            obj = null;
            try {
                realKey = new String(k, "UTF-8");
                cacheGroup = RedisConstant.REDIS_CALL_STAT_CACHE_PRE + DateUtils.getCurDateMinuteNoSep();
                cacheKey = realKey + "," + RedisConstant.OPER_TYPE_SET;
                obj = LocalCacheUtil.get(cacheGroup, cacheKey);
                if (obj != null) {
                    list = (CopyOnWriteArrayList<RedisCallInf>)obj;
                }
                else {
                    list = new CopyOnWriteArrayList<RedisCallInf>();
                }
            }
            catch (Exception e) {
                RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u9884\u5904\u7406\u53d1\u751f\u5f02\u5e38:", (Throwable)e);
            }
            valueBytes = this.serializer.serialize((Object)value);
            if (list == null || list.size() >= 500) {
                return jedis.set(k, valueBytes);
            }
            else {
                beginTm = System.currentTimeMillis();
                result = jedis.set(k, valueBytes);
                endTm = System.currentTimeMillis();
                callDur = endTm - beginTm;
                valSize = ((valueBytes != null) ? valueBytes.length : 0);
                list.add(new RedisCallInf(realKey, callDur, valSize, RedisConstant.OPER_TYPE_SET, -1));
                if (obj == null) {
                    try {
                        LocalCacheUtil.put(cacheGroup, cacheKey, (Object)list, Long.valueOf(180L), 2000L);
                    }
                    catch (Exception e2) {
                        RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u653e\u5165\u672c\u5730\u7f13\u5b58\u53d1\u751f\u5f02\u5e38:", (Throwable)e2);
                    }
                }
                return result;
            }
        }, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void set(final String key, final T value, final CacheTypeEnum cacheType) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.set, this, this.appName, this.notProdEnv);
        final byte[] valueBytes;
        final String result;
        String realKey;
        final String res = this.doCommand(key, (k, jedis) -> {
            valueBytes = this.serializer.serialize((Object)value);
            result = jedis.set(k, valueBytes);
            if ("OK".equalsIgnoreCase(result) && CacheTypeEnum.LOCAL.equals(cacheType)) {
                realKey = new String(k, "UTF-8");
                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes);
                RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
            }
            return result;
        }, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void set(final String key, final T value, final CacheTypeEnum cacheType, final long localCacheExpire) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.set, this, this.appName, this.notProdEnv);
        final byte[] valueBytes;
        final String result;
        String realKey;
        final String res = this.doCommand(key, (k, jedis) -> {
            valueBytes = this.serializer.serialize((Object)value);
            result = jedis.set(k, valueBytes);
            if ("OK".equalsIgnoreCase(result) && CacheTypeEnum.LOCAL.equals(cacheType) && localCacheExpire > 0L) {
                realKey = new String(k, "UTF-8");
                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes, Long.valueOf(localCacheExpire));
                RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
            }
            return result;
        }, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void set(final String key, final T value, final boolean isFullKey) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.set, this, this.appName, this.notProdEnv);
        final String res = this.doCommand(key, (k, jedis) -> jedis.set(k, this.serializer.serialize((Object)value)), isFullKey, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void set(final String key, final T value, final boolean isFullKey, final CacheTypeEnum cacheType) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.set, this, this.appName, this.notProdEnv);
        final byte[] valueBytes;
        final String result;
        String realKey;
        final String res = this.doCommand(key, (k, jedis) -> {
            valueBytes = this.serializer.serialize((Object)value);
            result = jedis.set(k, valueBytes);
            if ("OK".equalsIgnoreCase(result) && CacheTypeEnum.LOCAL.equals(cacheType)) {
                realKey = new String(k, "UTF-8");
                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes);
                RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
            }
            return result;
        }, isFullKey, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void set(final String key, final T value, final boolean isFullKey, final CacheTypeEnum cacheType, final long localCacheExpire) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.set, this, this.appName, this.notProdEnv);
        final byte[] valueBytes;
        final String result;
        String realKey;
        final String res = this.doCommand(key, (k, jedis) -> {
            valueBytes = this.serializer.serialize((Object)value);
            result = jedis.set(k, valueBytes);
            if ("OK".equalsIgnoreCase(result) && CacheTypeEnum.LOCAL.equals(cacheType) && localCacheExpire > 0L) {
                realKey = new String(k, "UTF-8");
                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes, Long.valueOf(localCacheExpire));
                RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
            }
            return result;
        }, isFullKey, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void setex(final String key, final T value, final int expire) {
        this.setex(key, value, expire, false);
    }
    
    @Override
    public <T> void setex(final String key, final T value, final int expire, final boolean isFullKey) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.setEx, this, this.appName, this.notProdEnv);
        String realKey;
        CopyOnWriteArrayList<RedisCallInf> list;
        String cacheGroup;
        String cacheKey;
        Object obj;
        final byte[] valueBytes;
        long beginTm;
        String result;
        long endTm;
        long callDur;
        int valSize;
        final String res = this.doCommand(key, (k, jedis) -> {
            realKey = null;
            list = null;
            cacheGroup = null;
            cacheKey = null;
            obj = null;
            try {
                realKey = new String(k, "UTF-8");
                cacheGroup = RedisConstant.REDIS_CALL_STAT_CACHE_PRE + DateUtils.getCurDateMinuteNoSep();
                cacheKey = realKey + "," + RedisConstant.OPER_TYPE_SETEX;
                obj = LocalCacheUtil.get(cacheGroup, cacheKey);
                if (obj != null) {
                    list = (CopyOnWriteArrayList<RedisCallInf>)obj;
                }
                else {
                    list = new CopyOnWriteArrayList<RedisCallInf>();
                }
            }
            catch (Exception e) {
                RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u9884\u5904\u7406\u53d1\u751f\u5f02\u5e38:", (Throwable)e);
            }
            valueBytes = this.serializer.serialize((Object)value);
            if (list == null || list.size() >= 500) {
                return jedis.setex(k, expire, valueBytes);
            }
            else {
                beginTm = System.currentTimeMillis();
                result = jedis.setex(k, expire, valueBytes);
                endTm = System.currentTimeMillis();
                callDur = endTm - beginTm;
                valSize = ((valueBytes != null) ? valueBytes.length : 0);
                list.add(new RedisCallInf(realKey, callDur, valSize, RedisConstant.OPER_TYPE_SETEX, expire));
                if (obj == null) {
                    try {
                        LocalCacheUtil.put(cacheGroup, cacheKey, (Object)list, Long.valueOf(180L), 2000L);
                    }
                    catch (Exception e2) {
                        RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u653e\u5165\u672c\u5730\u7f13\u5b58\u53d1\u751f\u5f02\u5e38:", (Throwable)e2);
                    }
                }
                return result;
            }
        }, isFullKey, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void setex(final String key, final T value, final int expire, final CacheTypeEnum cacheType) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.setEx, this, this.appName, this.notProdEnv);
        final byte[] valueBytes;
        final String result;
        String realKey;
        final String res = this.doCommand(key, (k, jedis) -> {
            valueBytes = this.serializer.serialize((Object)value);
            result = jedis.setex(k, expire, valueBytes);
            if ("OK".equalsIgnoreCase(result) && CacheTypeEnum.LOCAL.equals(cacheType)) {
                realKey = new String(k, "UTF-8");
                if (expire > 5) {
                    LocalCacheUtil.put(realKey, realKey, (Object)valueBytes, Long.valueOf(expire - 5L));
                }
                if (expire > 10) {
                    RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
                }
            }
            return result;
        }, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> void setex(final String key, final T value, final int expire, final CacheTypeEnum cacheType, final long localCacheExpire) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.setEx, this, this.appName, this.notProdEnv);
        final byte[] valueBytes;
        final String result;
        String realKey;
        final String res = this.doCommand(key, (k, jedis) -> {
            valueBytes = this.serializer.serialize((Object)value);
            result = jedis.setex(k, expire, valueBytes);
            if ("OK".equalsIgnoreCase(result) && CacheTypeEnum.LOCAL.equals(cacheType) && localCacheExpire > 0L && localCacheExpire <= expire) {
                realKey = new String(k, "UTF-8");
                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes, Long.valueOf(localCacheExpire));
                if (expire > 10) {
                    RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
                }
            }
            return result;
        }, redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <T> boolean setnx(final String key, final T value, final int expire) {
        Long res = this.doCommand(key, (k, jedis) -> jedis.setnx(k, this.serializer.serialize((Object)value)));
        boolean rv = res.intValue() == 1;
        if (rv && expire > 0) {
            res = this.doCommand(key, (k, jedis) -> jedis.expire(k, expire));
            rv = (res.intValue() == 1);
        }
        return rv;
    }
    
    @Override
    public <T> boolean setnx(final String key, final T value, final int expire, final CacheTypeEnum cacheType) {
        Long res = this.doCommand(key, (k, jedis) -> jedis.setnx(k, this.serializer.serialize((Object)value)));
        boolean rv = res.intValue() == 1;
        if (rv && expire > 0) {
            final Long result;
            String realKey;
            byte[] valueBytes;
            res = this.doCommand(key, (k, jedis) -> {
                result = jedis.expire(k, expire);
                if (result.intValue() == 1 && CacheTypeEnum.LOCAL.equals(cacheType)) {
                    realKey = new String(k, "UTF-8");
                    valueBytes = this.serializer.serialize((Object)value);
                    if (expire > 5) {
                        LocalCacheUtil.put(realKey, realKey, (Object)valueBytes, Long.valueOf(expire - 5L));
                    }
                    if (expire > 10) {
                        RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
                    }
                }
                return result;
            });
            rv = (res.intValue() == 1);
        }
        return rv;
    }
    
    @Override
    public <T> boolean setnx(final String key, final T value, final int expire, final CacheTypeEnum cacheType, final long localCacheExpire) {
        Long res = this.doCommand(key, (k, jedis) -> jedis.setnx(k, this.serializer.serialize((Object)value)));
        boolean rv = res.intValue() == 1;
        if (rv && expire > 0) {
            final Long result;
            String realKey;
            byte[] valueBytes;
            res = this.doCommand(key, (k, jedis) -> {
                result = jedis.expire(k, expire);
                if (result.intValue() == 1 && CacheTypeEnum.LOCAL.equals(cacheType) && localCacheExpire > 0L && localCacheExpire <= expire) {
                    realKey = new String(k, "UTF-8");
                    valueBytes = this.serializer.serialize((Object)value);
                    LocalCacheUtil.put(realKey, realKey, (Object)valueBytes, Long.valueOf(localCacheExpire));
                    if (expire > 10) {
                        RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
                    }
                }
                return result;
            });
            rv = (res.intValue() == 1);
        }
        return rv;
    }
    
    @Override
    public <T> T get(final String key) {
        return this.get(key, false);
    }
    
    @Override
    public <T> T getWithoutSerialize(final String key) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.get, this, this.appName, this.notProdEnv);
        final byte[] result;
        return this.doCommand(key, (k, jedis) -> {
            result = jedis.get(k);
            if (result == null) {
                return null;
            }
            else {
                return (T)new String(result);
            }
        }, false, redisMonitor);
    }
    
    @Override
    public <T> T get(final String key, final CacheTypeEnum cacheType) {
        return this.get(key, cacheType, 10L);
    }
    
    @Override
    public <T> T get(final String key, final CacheTypeEnum cacheType, final long localCacheExpire) {
        return this.get(key, false, cacheType, localCacheExpire);
    }
    
    @Override
    public <T> T get(final String key, final boolean isFullKey) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.get, this, this.appName, this.notProdEnv);
        String realKey;
        CopyOnWriteArrayList<RedisCallInf> list;
        String cacheGroup;
        String cacheKey;
        Object obj;
        final long beginTm;
        final byte[] resultBytes;
        final long endTm;
        final Object result;
        long callDur;
        int valSize;
        return this.doCommand(key, (k, jedis) -> {
            realKey = null;
            list = null;
            cacheGroup = null;
            cacheKey = null;
            obj = null;
            try {
                realKey = new String(k, "UTF-8");
                cacheGroup = RedisConstant.REDIS_CALL_STAT_CACHE_PRE + DateUtils.getCurDateMinuteNoSep();
                cacheKey = realKey + "," + RedisConstant.OPER_TYPE_GET;
                obj = LocalCacheUtil.get(cacheGroup, cacheKey);
                if (obj != null) {
                    list = (CopyOnWriteArrayList<RedisCallInf>)obj;
                }
                else {
                    list = new CopyOnWriteArrayList<RedisCallInf>();
                }
            }
            catch (Exception e) {
                RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u9884\u5904\u7406\u53d1\u751f\u5f02\u5e38:", (Throwable)e);
            }
            beginTm = System.currentTimeMillis();
            resultBytes = jedis.get(k);
            endTm = System.currentTimeMillis();
            result = ((resultBytes == null) ? null : this.serializer.deserialize(resultBytes));
            if (list == null || list.size() >= 500) {
                return result;
            }
            else {
                callDur = endTm - beginTm;
                valSize = ((resultBytes != null) ? resultBytes.length : 0);
                list.add(new RedisCallInf(realKey, callDur, valSize, RedisConstant.OPER_TYPE_GET));
                if (obj == null) {
                    try {
                        LocalCacheUtil.put(cacheGroup, cacheKey, (Object)list, Long.valueOf(180L), 2000L);
                    }
                    catch (Exception e2) {
                        RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u653e\u5165\u672c\u5730\u7f13\u5b58\u53d1\u751f\u5f02\u5e38:", (Throwable)e2);
                    }
                }
                return result;
            }
        }, isFullKey, redisMonitor);
    }
    
    @Override
    public <T> T get(final String key, final boolean isFullKey, final CacheTypeEnum cacheType, final long localCacheExpire) {
        return this.get(key, isFullKey, cacheType, localCacheExpire, true);
    }
    
    @Override
    public <T> T get(final String key, final boolean isFullKey, final CacheTypeEnum cacheType, final long localCacheExpire, final boolean isMonitor) {
        T result = null;
        RedisMonitor redisMonitor = null;
        if (isMonitor) {
            redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.get, this, this.appName, this.notProdEnv);
        }
        try {
            String realKey;
            byte[] valueBytes;
            byte[] valueBytes2;
            Long ttlValue;
            Object value;
            result = this.doCommand(key, (k, jedis) -> {
                if (CacheTypeEnum.REDIS.equals(cacheType)) {
                    return this.serializer.deserialize(jedis.get(k));
                }
                else {
                    realKey = new String(k, "UTF-8");
                    valueBytes = (byte[])LocalCacheUtil.get(realKey, realKey);
                    if (valueBytes != null) {
                        return this.serializer.deserialize(valueBytes);
                    }
                    else {
                        valueBytes2 = jedis.get(k);
                        if (valueBytes2 == null) {
                            return null;
                        }
                        else {
                            ttlValue = jedis.ttl(k);
                            if (localCacheExpire > 0L && ttlValue != null && (ttlValue > localCacheExpire || ttlValue == -1L)) {
                                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes2, Long.valueOf(localCacheExpire));
                            }
                            value = this.serializer.deserialize(valueBytes2);
                            if (ttlValue != null && (ttlValue > 10L || ttlValue == -1L)) {
                                RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
                            }
                            return value;
                        }
                    }
                }
            }, isFullKey, redisMonitor);
        }
        catch (Throwable e) {
            String fullKey = key;
            try {
                if (!isFullKey) {
                    fullKey = this.key(key);
                }
                final byte[] objBytes = RedisLocalFileUtil.getFromFile(fullKey);
                if (objBytes == null) {
                    return null;
                }
                result = (T)RedisLocalFileUtil.getObject(objBytes);
                LocalCacheUtil.put(fullKey, fullKey, (Object)this.serializer.serialize((Object)result), Long.valueOf(10L));
                RedisOperater.log.info("\u4ece\u672c\u5730redis\u6587\u4ef6\u83b7\u53d6key:{}\u5185\u5bb9\u4e3a:{}", (Object)fullKey, (Object)JsonUtils.objectToJson((Object)result));
                return result;
            }
            catch (Throwable ex) {
                RedisOperater.log.error("\u4ece\u672c\u5730redis\u6587\u4ef6\u83b7\u53d6key:{}\u5185\u5bb9\u53d1\u751fException:", (Object)fullKey, (Object)ex);
                throw new RuntimeException(String.format("\u4ece\u672c\u5730redis\u6587\u4ef6\u83b7\u53d6key:%s\u5185\u5bb9\u5931\u8d25!", fullKey));
            }
        }
        return result;
    }
    
    @Override
    public <T> T get(final String key, final CacheTypeEnum cacheType, final long localCacheExpire, final Object defaultValue) {
        return this.get(key, false, cacheType, localCacheExpire, defaultValue, true);
    }
    
    @Override
    public <T> T get(final String key, final boolean isFullKey, final CacheTypeEnum cacheType, final long localCacheExpire, final Object defaultValue, final boolean isMonitor) {
        T result = null;
        RedisMonitor redisMonitor = null;
        if (isMonitor) {
            redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.get, this, this.appName, this.notProdEnv);
        }
        try {
            String realKey;
            byte[] valueBytes;
            byte[] valueBytes2;
            Object value;
            boolean cacheDefaultFlag;
            Long ttlValue;
            result = this.doCommand(key, (k, jedis) -> {
                if (CacheTypeEnum.REDIS.equals(cacheType)) {
                    return this.serializer.deserialize(jedis.get(k));
                }
                else {
                    realKey = new String(k, "UTF-8");
                    valueBytes = (byte[])LocalCacheUtil.get(realKey, realKey);
                    if (valueBytes != null) {
                        return this.serializer.deserialize(valueBytes);
                    }
                    else {
                        valueBytes2 = jedis.get(k);
                        value = null;
                        cacheDefaultFlag = false;
                        if (valueBytes2 == null) {
                            if (defaultValue == null) {
                                return null;
                            }
                            else {
                                valueBytes2 = this.serializer.serialize(defaultValue);
                                value = defaultValue;
                                cacheDefaultFlag = true;
                            }
                        }
                        ttlValue = null;
                        if (localCacheExpire > 0L) {
                            if (cacheDefaultFlag) {
                                LocalCacheUtil.put(realKey, realKey, (Object)valueBytes2, Long.valueOf(localCacheExpire));
                            }
                            else {
                                ttlValue = jedis.ttl(k);
                                if (ttlValue != null && (ttlValue > localCacheExpire || ttlValue == -1L)) {
                                    LocalCacheUtil.put(realKey, realKey, (Object)valueBytes2, Long.valueOf(localCacheExpire));
                                }
                            }
                        }
                        if (value == null) {
                            value = this.serializer.deserialize(valueBytes2);
                        }
                        if (ttlValue != null && (ttlValue > 10L || ttlValue == -1L)) {
                            RedisConstant.redisDataMap.put(realKey, RedisLocalFileUtil.getObjectBytes(value));
                        }
                        return value;
                    }
                }
            }, isFullKey, redisMonitor);
        }
        catch (Throwable e) {
            String fullKey = key;
            try {
                if (!isFullKey) {
                    fullKey = this.key(key);
                }
                final byte[] objBytes = RedisLocalFileUtil.getFromFile(fullKey);
                if (objBytes == null) {
                    return null;
                }
                result = (T)RedisLocalFileUtil.getObject(objBytes);
                LocalCacheUtil.put(fullKey, fullKey, (Object)this.serializer.serialize((Object)result), Long.valueOf(10L));
                RedisOperater.log.info("\u4ece\u672c\u5730redis\u6587\u4ef6\u83b7\u53d6key:{}\u5185\u5bb9\u4e3a:{}", (Object)fullKey, (Object)JsonUtils.objectToJson((Object)result));
                return result;
            }
            catch (Throwable ex) {
                RedisOperater.log.error("\u4ece\u672c\u5730redis\u6587\u4ef6\u83b7\u53d6key:{}\u5185\u5bb9\u53d1\u751fException:", (Object)fullKey, (Object)ex);
                throw new RuntimeException(String.format("\u4ece\u672c\u5730redis\u6587\u4ef6\u83b7\u53d6key:%s\u5185\u5bb9\u5931\u8d25!", fullKey));
            }
        }
        return result;
    }
    
    @Override
    public <T> T getSet(final String key, final T value) {
        return this.doCommand(key, (k, jedis) -> this.serializer.deserialize(jedis.getSet(k, this.serializer.serialize((Object)value))));
    }
    
    @Override
    public Long delete(final String key) {
        return this.delete(key, false);
    }
    
    @Override
    public Long delete(final String key, final boolean isFullKey) {
        RedisOperater.log.debug("zsf-redis-delete-key=namespace:{}-key:{}-isFullKey:{}", new Object[] { this.getNamespace(), key, isFullKey });
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.delete, this, this.appName, this.notProdEnv);
        final Long result;
        final String realKey;
        return this.doCommand(key, (k, jedis) -> {
            result = jedis.del(k);
            realKey = new String(k, "UTF-8");
            if (LocalCacheUtil.get(realKey, realKey) != null) {
                LocalCacheUtil.remove(realKey, realKey);
            }
            if (RedisConstant.redisDataMap.get(realKey) != null) {
                RedisConstant.redisDataMap.remove(realKey);
            }
            return result;
        }, isFullKey, redisMonitor);
    }
    
    @Override
    public boolean expire(final String key, final int expire) {
        return this.expire(key, expire, false);
    }
    
    @Override
    public boolean expire(final String key, final int expire, final boolean isFullKey) {
        return this.doCommand(key, (k, jedis) -> jedis.expire(k, expire).intValue() == 1, isFullKey);
    }
    
    @Override
    public long incr(final String key) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.incr, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> jedis.incr(k), redisMonitor);
    }
    
    @Override
    public long incrBy(final String key, final int increment) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.incr, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> jedis.incrBy(k, increment), redisMonitor);
    }
    
    @Override
    public long decr(final String key) {
        return this.doCommand(key, (k, jedis) -> jedis.decr(k));
    }
    
    @Override
    public long decrBy(final String key, final int decrement) {
        return this.doCommand(key, (k, jedis) -> jedis.decrBy(k, decrement));
    }
    
    @Override
    public <F> Boolean hexists(final String key, final F field) {
        return this.doCommand(key, (k, jedis) -> jedis.hexists(k, this.field(field)));
    }
    
    @Override
    public <F, T> long hset(final String key, final F field, final T value) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.hset, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> jedis.hset(k, this.field(field), this.serializer.serialize((Object)value)), redisMonitor);
    }
    
    @Override
    public <F, T> long hset(final String key, final F field, final T value, final boolean isFullKey) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, value, RedisOperTypeEnum.hset, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> jedis.hset(k, this.field(field), this.serializer.serialize((Object)value)), isFullKey, redisMonitor);
    }
    
    @Override
    public <F, T> boolean hsetnx(final String key, final F field, final T value) {
        return this.doCommand(key, (k, jedis) -> jedis.hsetnx(k, this.field(field), this.serializer.serialize((Object)value)).intValue() == 1);
    }
    
    @Override
    public <F, T> void hmset(final String key, final Map<F, T> fieldValues) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, fieldValues, RedisOperTypeEnum.hmset, this, this.appName, this.notProdEnv);
        final Map<byte[], byte[]> hash = new HashMap<byte[], byte[]>(fieldValues.size());
        final Iterator<Map.Entry<F, T>> it = fieldValues.entrySet().iterator();
        try {
            while (it.hasNext()) {
                final Map.Entry<F, T> item = it.next();
                hash.put(this.field(item.getKey()), this.serializer.serialize((Object)item.getValue()));
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        final String res = this.doCommand(key, (k, jedis) -> jedis.hmset(k, hash), redisMonitor);
        if (!"OK".equalsIgnoreCase(res)) {
            throw new RuntimeException(res);
        }
    }
    
    @Override
    public <F, T> T hget(final String key, final F field) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.hget, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> this.serializer.deserialize(jedis.hget(k, this.field(field))), redisMonitor);
    }
    
    @Override
    public <F, T> T hget(final String key, final F field, final boolean isFullKey) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.hget, this, this.appName, this.notProdEnv);
        return this.doCommand(key, (k, jedis) -> this.serializer.deserialize(jedis.hget(k, this.field(field))), isFullKey, redisMonitor);
    }
    
    @Override
    public <T> Map<String, T> hgetAll(final String key) {
        return this.hgetAll(key, false);
    }
    
    @Override
    public <T> Map<String, T> hgetAll(final boolean isMonitor, final String key) {
        return this.hgetAll(isMonitor, key, false);
    }
    
    @Override
    public <T> Map<String, T> hgetAll(final String key, final boolean isFullKey) {
        return this.hgetAll(true, key, isFullKey);
    }
    
    @Override
    public <T> Map<String, T> hgetAll(final boolean isMonitor, final String key, final boolean isFullKey) {
        RedisMonitor redisMonitor = null;
        if (isMonitor) {
            redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.hgetAll, this, this.appName, this.notProdEnv);
        }
        final Map<byte[], byte[]> map = this.doCommand(key, (k, jedis) -> jedis.hgetAll(k), isFullKey, redisMonitor);
        Map<String, T> res = null;
        if (null != map) {
            res = new HashMap<String, T>(map.size());
            final Iterator<Map.Entry<byte[], byte[]>> it = map.entrySet().iterator();
            try {
                while (it.hasNext()) {
                    final Map.Entry<byte[], byte[]> item = it.next();
                    res.put(new String(item.getKey(), "UTF-8"), (T)this.serializer.deserialize((byte[])item.getValue()));
                }
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return res;
    }
    
    @Override
    public <T> List<T> hmget(final String key, final Object... field) {
        return this.hmget(false, key, field);
    }
    
    @Override
    public <T> List<T> hmget(final boolean isFullKey, final String key, final Object... field) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.hmget, this, this.appName, this.notProdEnv);
        if (null == field || field.length == 0) {
            throw new IllegalArgumentException("\u7f3afield\u53c2\u6570");
        }
        final byte[][] fields = new byte[field.length][];
        for (int i = 0; i < field.length; ++i) {
            fields[i] = this.field(field[i]);
        }
        final List<byte[]> list = this.doCommand(key, (k, jedis) -> jedis.hmget(k, fields), isFullKey, redisMonitor);
        List<T> res = null;
        if (null != list) {
            res = new ArrayList<T>(list.size());
            try {
                for (final byte[] data : list) {
                    res.add((T)this.serializer.deserialize(data));
                }
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return res;
    }
    
    @Override
    public long hdel(final String key, final Object... field) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.hdel, this, this.appName, this.notProdEnv);
        if (null == field || field.length == 0) {
            throw new IllegalArgumentException("\u7f3afield\u53c2\u6570");
        }
        final byte[][] fields = new byte[field.length][];
        for (int i = 0; i < field.length; ++i) {
            fields[i] = this.field(field[i]);
        }
        return this.doCommand(key, (k, jedis) -> jedis.hdel(k, fields), redisMonitor);
    }
    
    @Override
    public long hdel(final boolean isFullKey, final String key, final Object field) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.hdel, this, this.appName, this.notProdEnv);
        if (null == field) {
            throw new IllegalArgumentException("\u7f3afield\u53c2\u6570");
        }
        final byte[][] fields = { this.field(field) };
        return this.doCommand(key, (k, jedis) -> jedis.hdel(k, fields), isFullKey, redisMonitor);
    }
    
    @Override
    public <F> long hincrBy(final String key, final F field, final int increment) {
        return this.doCommand(key, (k, jedis) -> jedis.hincrBy(k, this.field(field), increment));
    }
    
    @Override
    public <T> T lpop(final String key) {
        return this.doCommand(key, (k, jedis) -> this.serializer.deserialize(jedis.lpop(k)));
    }
    
    @Override
    public <T> T rpop(final String key) {
        return this.doCommand(key, (k, jedis) -> this.serializer.deserialize(jedis.rpop(k)));
    }
    
    @Override
    public <T> Long lpush(final String key, final T... value) {
        return this.doCommand(key, (k, jedis) -> jedis.lpush(k, new byte[][] { this.serializer.serialize((Object)value) }));
    }
    
    @Override
    public <T> Long lpushx(final String key, final T... value) {
        return this.doCommand(key, (k, jedis) -> jedis.lpushx(k, new byte[][] { this.serializer.serialize((Object)value) }));
    }
    
    @Override
    public <T> Long rpush(final String key, final T... value) {
        return this.doCommand(key, (k, jedis) -> jedis.rpush(k, new byte[][] { this.serializer.serialize((Object)value) }));
    }
    
    @Override
    public <T> Long rpushx(final String key, final T... value) {
        return this.doCommand(key, (k, jedis) -> jedis.rpushx(k, new byte[][] { this.serializer.serialize((Object)value) }));
    }
    
    @Override
    public <T> T lindex(final String key, final int index) {
        return this.doCommand(key, (k, jedis) -> this.serializer.deserialize(jedis.lindex(k, index)));
    }
    
    @Override
    public <T> Long linsertAfter(final String key, final T pivot, final T value) {
        return this.doCommand(key, (k, jedis) -> jedis.linsertAfter(k, this.serializer.serialize((Object)pivot), this.serializer.serialize((Object)value)));
    }
    
    @Override
    public <T> Long linsertBefore(final String key, final T pivot, final T value) {
        return this.doCommand(key, (k, jedis) -> jedis.linsertBefore(k, this.serializer.serialize((Object)pivot), this.serializer.serialize((Object)value)));
    }
    
    @Override
    public Long llen(final String key) {
        return this.doCommand(key, (k, jedis) -> jedis.llen(k));
    }
    
    @Override
    public <T> List<T> lrange(final String key, final int start, final int stop) {
        final List<byte[]> datas;
        ArrayList res;
        final Iterator<byte[]> iterator;
        byte[] data;
        return this.doCommand(key, (k, jedis) -> {
            datas = jedis.lrange(k, start, stop);
            res = null;
            if (null != datas && datas.size() > 0) {
                res = new ArrayList<Object>(datas.size());
                datas.iterator();
                while (iterator.hasNext()) {
                    data = iterator.next();
                    res.add(this.serializer.deserialize(data));
                }
            }
            return (List<Object>)res;
        });
    }
    
    @Override
    public <T> long lrem(final String key, final int count, final T value) {
        return this.doCommand(key, (k, jedis) -> jedis.lrem(k, count, this.serializer.serialize((Object)value)));
    }
    
    @Override
    public <T> long lrem(final String key, final int count, final byte[] value) {
        return this.doCommand(key, (k, jedis) -> jedis.lrem(k, count, value));
    }
    
    @Override
    public <T> boolean lset(final String key, final int index, final T value) {
        return this.doCommand(key, (k, jedis) -> "OK".equalsIgnoreCase(jedis.lset(k, index, this.serializer.serialize((Object)value))));
    }
    
    @Override
    public boolean ltrim(final String key, final int start, final int stop) {
        return this.doCommand(key, (k, jedis) -> "OK".equalsIgnoreCase(jedis.ltrim(k, start, stop)));
    }
    
    @Override
    public <T> long zdd(final String key, final double score, final T member) {
        return this.doCommand(key, (k, jedis) -> jedis.zadd(k, score, this.serializer.serialize((Object)member)));
    }
    
    @Override
    public long zcount(final String key, final double min, final double max) {
        return this.doCommand(key, (k, jedis) -> jedis.zcount(k, min, max));
    }
    
    @Override
    public <T> Set<T> zrange(final String key, final long start, final long end) {
        final Set<byte[]> set = this.doCommand(key, (k, jedis) -> jedis.zrange(k, start, end));
        return this.convertToLinkedHashSet(set);
    }
    
    @Override
    public Set<ZSetOperations.TypedTuple<Object>> zrangeWithScores(final String key, final long start, final long end) {
        final Set<Tuple> set = this.doCommand(key, (k, jedis) -> jedis.zrangeWithScores(k, start, end));
        Set<ZSetOperations.TypedTuple<Object>> res = null;
        if (null != set) {
            res = new LinkedHashSet<ZSetOperations.TypedTuple<Object>>(set.size());
            for (final Tuple s : set) {
                try {
                    final ZSetOperations.TypedTuple<Object> tmp = (ZSetOperations.TypedTuple<Object>)new DefaultTypedTuple(this.serializer.deserialize(s.getBinaryElement()), Double.valueOf(s.getScore()));
                    res.add(tmp);
                }
                catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return res;
    }
    
    @Override
    public Set<Object> zrangeByScore(final String key, final double start, final double stop) {
        final Set<byte[]> set = this.doCommand(key, (k, jedis) -> jedis.zrangeByScore(k, start, stop));
        return this.convertToLinkedHashSet(set);
    }
    
    @Override
    public Set<ZSetOperations.TypedTuple<Object>> zrangeByScoreWithScores(final String key, final double start, final double stop) {
        final Set<Tuple> set = this.doCommand(key, (k, jedis) -> jedis.zrangeByScoreWithScores(k, start, stop));
        Set<ZSetOperations.TypedTuple<Object>> res = null;
        if (null != set) {
            res = new LinkedHashSet<ZSetOperations.TypedTuple<Object>>(set.size());
            for (final Tuple s : set) {
                try {
                    final ZSetOperations.TypedTuple<Object> tmp = (ZSetOperations.TypedTuple<Object>)new DefaultTypedTuple(this.serializer.deserialize(s.getBinaryElement()), Double.valueOf(s.getScore()));
                    res.add(tmp);
                }
                catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return res;
    }
    
    @Override
    public long zrem(final String key, final Object... member) {
        if (null == member || member.length == 0) {
            throw new IllegalArgumentException("\u7f3amember\u53c2\u6570");
        }
        final byte[][] members = new byte[member.length][];
        try {
            for (int i = 0; i < member.length; ++i) {
                members[i] = this.serializer.serialize(member[i]);
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        return this.doCommand(key, (k, jedis) -> jedis.zrem(k, members));
    }
    
    @Override
    public Object eval(final String script, final String key, final Object... arg) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: aload_3         /* arg */
        //     2: if_acmpeq       72
        //     5: aload_3         /* arg */
        //     6: arraylength    
        //     7: ifle            72
        //    10: new             Ljava/util/ArrayList;
        //    13: dup            
        //    14: aload_3         /* arg */
        //    15: arraylength    
        //    16: invokespecial   java/util/ArrayList.<init>:(I)V
        //    19: astore          args
        //    21: iconst_0       
        //    22: istore          i
        //    24: iload           i
        //    26: aload_3         /* arg */
        //    27: arraylength    
        //    28: if_icmpge       57
        //    31: aload           args
        //    33: aload_3         /* arg */
        //    34: iload           i
        //    36: aaload         
        //    37: invokestatic    java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        //    40: ldc             "UTF-8"
        //    42: invokevirtual   java/lang/String.getBytes:(Ljava/lang/String;)[B
        //    45: invokeinterface java/util/List.add:(Ljava/lang/Object;)Z
        //    50: pop            
        //    51: iinc            i, 1
        //    54: goto            24
        //    57: goto            75
        //    60: astore          e
        //    62: new             Ljava/lang/RuntimeException;
        //    65: dup            
        //    66: aload           e
        //    68: invokespecial   java/lang/RuntimeException.<init>:(Ljava/lang/Throwable;)V
        //    71: athrow         
        //    72: aconst_null    
        //    73: astore          args
        //    75: aload_0         /* this */
        //    76: aload_2         /* key */
        //    77: aload_1         /* script */
        //    78: aload           args
        //    80: invokedynamic   BootstrapMethod #61, callback:(Ljava/lang/String;Ljava/util/List;)Lcom/zycfc/zsf/boot/redis/RedisOperater$RedisCallback;
        //    85: invokespecial   com/zycfc/zsf/boot/redis/RedisOperater.doCommand:(Ljava/lang/String;Lcom/zycfc/zsf/boot/redis/RedisOperater$RedisCallback;)Ljava/lang/Object;
        //    88: areturn        
        //    StackMapTable: 00 05 FD 00 18 07 02 1B 01 FA 00 20 42 07 01 FA FA 00 0B FC 00 02 07 02 1B
        //    Exceptions:
        //  Try           Handler
        //  Start  End    Start  End    Type                 
        //  -----  -----  -----  -----  ---------------------
        //  21     57     60     72     Ljava/lang/Exception;
        // 
        // The error that occurred was:
        // 
        // java.lang.IllegalStateException: Expression is linked from several locations: (k:byte[], jedis:RedisBinaryCommand) -> {
        //     args = args:List<byte[]>
        //     keys = initobject(ArrayList<E>::<init>, ldc:int(1))
        //     invokeinterface:boolean(List<byte[]>::add, keys:List<byte[]>, k:byte[])
        //     return:Object(invokeinterface:Object(RedisBinaryCommand::eval, jedis:RedisBinaryCommand, invokevirtual:byte[](String::getBytes, script:String, ldc:String("UTF-8")), keys:List<byte[]>, args:List<byte[]>))
        // }
        //     at com.strobel.decompiler.ast.Error.expressionLinkedFromMultipleLocations(Error.java:27)
        //     at com.strobel.decompiler.ast.GotoRemoval.traverseGraph(GotoRemoval.java:88)
        //     at com.strobel.decompiler.ast.GotoRemoval.removeGotos(GotoRemoval.java:52)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:294)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at us.deathmarine.luyten.FileSaver.doSaveJarDecompiled(FileSaver.java:192)
        //     at us.deathmarine.luyten.FileSaver.access$300(FileSaver.java:45)
        //     at us.deathmarine.luyten.FileSaver$4.run(FileSaver.java:112)
        //     at java.lang.Thread.run(Thread.java:750)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    @Override
    public Object evalSha(final byte[] sha1, final String key, final Object... arg) {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     1: aload_3         /* arg */
        //     2: if_acmpeq       72
        //     5: aload_3         /* arg */
        //     6: arraylength    
        //     7: ifle            72
        //    10: new             Ljava/util/ArrayList;
        //    13: dup            
        //    14: aload_3         /* arg */
        //    15: arraylength    
        //    16: invokespecial   java/util/ArrayList.<init>:(I)V
        //    19: astore          args
        //    21: iconst_0       
        //    22: istore          i
        //    24: iload           i
        //    26: aload_3         /* arg */
        //    27: arraylength    
        //    28: if_icmpge       57
        //    31: aload           args
        //    33: aload_3         /* arg */
        //    34: iload           i
        //    36: aaload         
        //    37: invokestatic    java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
        //    40: ldc             "UTF-8"
        //    42: invokevirtual   java/lang/String.getBytes:(Ljava/lang/String;)[B
        //    45: invokeinterface java/util/List.add:(Ljava/lang/Object;)Z
        //    50: pop            
        //    51: iinc            i, 1
        //    54: goto            24
        //    57: goto            75
        //    60: astore          e
        //    62: new             Ljava/lang/RuntimeException;
        //    65: dup            
        //    66: aload           e
        //    68: invokespecial   java/lang/RuntimeException.<init>:(Ljava/lang/Throwable;)V
        //    71: athrow         
        //    72: aconst_null    
        //    73: astore          args
        //    75: aload_0         /* this */
        //    76: aload_2         /* key */
        //    77: aload_1         /* sha1 */
        //    78: aload           args
        //    80: invokedynamic   BootstrapMethod #62, callback:([BLjava/util/List;)Lcom/zycfc/zsf/boot/redis/RedisOperater$RedisCallback;
        //    85: invokespecial   com/zycfc/zsf/boot/redis/RedisOperater.doCommand:(Ljava/lang/String;Lcom/zycfc/zsf/boot/redis/RedisOperater$RedisCallback;)Ljava/lang/Object;
        //    88: areturn        
        //    StackMapTable: 00 05 FD 00 18 07 02 1B 01 FA 00 20 42 07 01 FA FA 00 0B FC 00 02 07 02 1B
        //    Exceptions:
        //  Try           Handler
        //  Start  End    Start  End    Type                 
        //  -----  -----  -----  -----  ---------------------
        //  21     57     60     72     Ljava/lang/Exception;
        // 
        // The error that occurred was:
        // 
        // java.lang.IllegalStateException: Expression is linked from several locations: (k:byte[], jedis:RedisBinaryCommand) -> {
        //     args = args:List<byte[]>
        //     keys = initobject(ArrayList<E>::<init>, ldc:int(1))
        //     invokeinterface:boolean(List<byte[]>::add, keys:List<byte[]>, k:byte[])
        //     return:Object(invokeinterface:Object(RedisBinaryCommand::evalsha, jedis:RedisBinaryCommand, sha1:byte[], keys:List<byte[]>, args:List<byte[]>))
        // }
        //     at com.strobel.decompiler.ast.Error.expressionLinkedFromMultipleLocations(Error.java:27)
        //     at com.strobel.decompiler.ast.GotoRemoval.traverseGraph(GotoRemoval.java:88)
        //     at com.strobel.decompiler.ast.GotoRemoval.removeGotos(GotoRemoval.java:52)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:294)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:214)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at us.deathmarine.luyten.FileSaver.doSaveJarDecompiled(FileSaver.java:192)
        //     at us.deathmarine.luyten.FileSaver.access$300(FileSaver.java:45)
        //     at us.deathmarine.luyten.FileSaver$4.run(FileSaver.java:112)
        //     at java.lang.Thread.run(Thread.java:750)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
    
    @Override
    public byte[] scriptLoad(final byte[] script, final String key) {
        return this.doCommand(key, (k, jedis) -> jedis.scriptLoad(script, k));
    }
    
    @Override
    public long sadd(final String key, final Object... member) {
        if (null == member || member.length == 0) {
            throw new IllegalArgumentException("\u7f3amember\u53c2\u6570");
        }
        final byte[][] members = new byte[member.length][];
        try {
            for (int i = 0; i < member.length; ++i) {
                members[i] = this.serializer.serialize(member[i]);
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        return this.doCommand(key, (k, jedis) -> jedis.sadd(k, members));
    }
    
    @Override
    public long scard(final String key) {
        return this.doCommand(key, (k, jedis) -> jedis.scard(k));
    }
    
    @Override
    public boolean sisMember(final String key, final Object member) {
        return this.doCommand(key, (k, jedis) -> jedis.sismember(k, this.serializer.serialize(member)));
    }
    
    @Override
    public Set<Object> smembers(final String key) {
        final Set<byte[]> vals = this.doCommand(key, (k, jedis) -> jedis.smembers(k));
        Set<Object> res = null;
        if (null != vals) {
            res = new HashSet<Object>(vals.size());
            for (final byte[] val : vals) {
                try {
                    res.add(this.serializer.deserialize(val));
                }
                catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return res;
    }
    
    @Override
    public <T> T spop(final String key) {
        final byte[] val = this.doCommand(key, (k, jedis) -> jedis.spop(k));
        try {
            return (T)this.serializer.deserialize(val);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    @Override
    public List<Object> srandMember(final String key, final int count) {
        final List<byte[]> vals = this.doCommand(key, (k, jedis) -> jedis.srandmember(k, count));
        return this.convertToObjectList(vals);
    }
    
    @Override
    public <T> T srandMember(final String key) {
        final byte[] val = this.doCommand(key, (k, jedis) -> jedis.srandmember(k));
        try {
            return (T)this.serializer.deserialize(val);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    @Override
    public long srem(final String key, final Object... member) {
        if (null == member || member.length == 0) {
            throw new IllegalArgumentException("\u7f3amember\u53c2\u6570");
        }
        final byte[][] members = new byte[member.length][];
        try {
            for (int i = 0; i < member.length; ++i) {
                members[i] = this.serializer.serialize(member[i]);
            }
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
        return this.doCommand(key, (k, jedis) -> jedis.srem(k, members));
    }
    
    public List<Object> convertToObjectList(final List<byte[]> vals) {
        List<Object> res = null;
        if (null != vals) {
            res = new ArrayList<Object>(vals.size());
            for (final byte[] val : vals) {
                try {
                    res.add(this.serializer.deserialize(val));
                }
                catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return res;
    }
    
    public <T> Set<T> convertToLinkedHashSet(final Set<byte[]> vals) {
        Set<T> res = null;
        if (null != vals) {
            res = new LinkedHashSet<T>(vals.size());
            for (final byte[] val : vals) {
                try {
                    res.add((T)this.serializer.deserialize(val));
                }
                catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return res;
    }
    
    @Override
    public String getNamespace() {
        String namespace = "";
        if (this.config.isNamespaceEnable()) {
            namespace = this.config.getNamespace();
        }
        if (null != namespace && namespace.trim().length() > 0) {
            namespace += ":";
        }
        else {
            namespace = "";
        }
        return namespace;
    }
    
    private <T> T doCommand(final String key, final RedisCallback<T> callback) {
        return this.doCommand(key, callback, false);
    }
    
    private <T> T doCommand(final String key, final RedisCallback<T> callback, final boolean isFullKey) {
        return this.doCommand(key, callback, isFullKey, null);
    }
    
    private <T> T doCommand(final String key, final RedisCallback<T> callback, final RedisMonitor redisMonitor) {
        return this.doCommand(key, callback, false, redisMonitor);
    }
    
    private <T> T doCommand(final String key, final RedisCallback<T> callback, final boolean isFullKey, final RedisMonitor redisMonitor) {
        final long begin = System.currentTimeMillis();
        String fullKey = key;
        if (!isFullKey) {
            fullKey = this.key(key);
        }
        try {
            return callback.callback(fullKey.getBytes("UTF-8"), this.redisCommand);
        }
        catch (Throwable ex) {
            RedisOperater.log.error("Throwable", ex);
            if (redisMonitor != null) {
                redisMonitor.setExeSts("F");
            }
            throw new RuntimeException(ex);
        }
        finally {
            final long end = System.currentTimeMillis();
            final long useTime = end - begin;
            if (redisMonitor != null) {
                if (redisMonitor.getExeSts() == null) {
                    redisMonitor.setExeSts("S");
                }
                redisMonitor.setEndTime(end);
                redisMonitor.setExeTm(useTime);
                redisMonitor.setKey(fullKey);
                redisMonitor.setKeySize(fullKey.length());
                RedisMonitorUtil.doLog(redisMonitor);
            }
            if (this.config.getSlowLogSlowerThan() > 0 && useTime > this.config.getSlowLogSlowerThan()) {
                RedisOperater.log.warn("execute redis command for key '{}' use time {}ms", (Object)fullKey, (Object)useTime);
            }
        }
    }
    
    @Override
    public List<String> multiGet(final Collection<String> keys) {
        final List<String> list = new ArrayList<String>();
        for (final String key : keys) {
            list.add(this.get(key, true));
        }
        return list;
    }
    
    @Override
    public <T> boolean setNxPx(final String key, final T value, final long expireTime) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.setNxPx, this, this.appName, this.notProdEnv);
        final String res = this.doCommand(key, (k, jedis) -> jedis.setNxPx(k, String.valueOf(value).getBytes("UTF-8"), "NX".getBytes("UTF-8"), "PX".getBytes("UTF-8"), expireTime), redisMonitor);
        return "OK".equalsIgnoreCase(res);
    }
    
    @Override
    public <T> boolean setNxPxWithSerialize(final String key, final T value, final long expireTime) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.setNxPx, this, this.appName, this.notProdEnv);
        final String res = this.doCommand(key, (k, jedis) -> jedis.setNxPx(k, this.serializer.serialize((Object)value), "NX".getBytes("UTF-8"), "PX".getBytes("UTF-8"), expireTime), redisMonitor);
        return "OK".equalsIgnoreCase(res);
    }
    
    @Override
    public <T> boolean setNxEx(final String key, final T value, final long expireTime) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.setNxEx, this, this.appName, this.notProdEnv);
        final String res = this.doCommand(key, (k, jedis) -> jedis.setNxPx(k, String.valueOf(value).getBytes("UTF-8"), "NX".getBytes("UTF-8"), "EX".getBytes("UTF-8"), expireTime), redisMonitor);
        return "OK".equalsIgnoreCase(res);
    }
    
    @Override
    public <T> boolean setNxExWithSerialize(final String key, final T value, final long expireTime) {
        final RedisMonitor redisMonitor = RedisMonitorUtil.assembleRedisMonitor(key, (Object)null, RedisOperTypeEnum.setNxEx, this, this.appName, this.notProdEnv);
        String realKey;
        CopyOnWriteArrayList<RedisCallInf> list;
        String cacheGroup;
        String cacheKey;
        Object obj;
        final byte[] valueBytes;
        long beginTm;
        String result;
        long endTm;
        long callDur;
        int valSize;
        final RedisCallInf redisCallInf;
        final Object o;
        final String res = this.doCommand(key, (k, jedis) -> {
            realKey = null;
            list = null;
            cacheGroup = null;
            cacheKey = null;
            obj = null;
            try {
                realKey = new String(k, "UTF-8");
                cacheGroup = RedisConstant.REDIS_CALL_STAT_CACHE_PRE + DateUtils.getCurDateMinuteNoSep();
                cacheKey = realKey + "," + RedisConstant.OPER_TYPE_SETNXEX;
                obj = LocalCacheUtil.get(cacheGroup, cacheKey);
                if (obj != null) {
                    list = (CopyOnWriteArrayList<RedisCallInf>)obj;
                }
                else {
                    list = new CopyOnWriteArrayList<RedisCallInf>();
                }
            }
            catch (Exception e) {
                RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u9884\u5904\u7406\u53d1\u751f\u5f02\u5e38:", (Throwable)e);
            }
            valueBytes = this.serializer.serialize((Object)value);
            if (list == null || list.size() >= 500) {
                return jedis.setNxPx(k, valueBytes, "NX".getBytes("UTF-8"), "EX".getBytes("UTF-8"), expireTime);
            }
            else {
                beginTm = System.currentTimeMillis();
                result = jedis.setNxPx(k, valueBytes, "NX".getBytes("UTF-8"), "EX".getBytes("UTF-8"), expireTime);
                endTm = System.currentTimeMillis();
                callDur = endTm - beginTm;
                valSize = ((valueBytes != null) ? valueBytes.length : 0);
                new RedisCallInf(realKey, callDur, valSize, RedisConstant.OPER_TYPE_SETNXEX, new Long(expireTime).intValue());
                ((CopyOnWriteArrayList<RedisCallInf>)o).add(redisCallInf);
                if (obj == null) {
                    try {
                        LocalCacheUtil.put(cacheGroup, cacheKey, (Object)list, Long.valueOf(180L), 2000L);
                    }
                    catch (Exception e2) {
                        RedisOperater.log.warn("Redis\u8c03\u7528\u7edf\u8ba1\u653e\u5165\u672c\u5730\u7f13\u5b58\u53d1\u751f\u5f02\u5e38:", (Throwable)e2);
                    }
                }
                return result;
            }
        }, redisMonitor);
        return "OK".equalsIgnoreCase(res);
    }
    
    @Override
    public Long ttl(final String key) {
        return this.ttl(key, false);
    }
    
    @Override
    public Long ttl(final String key, final boolean isFullKey) {
        final Long ttlValue = this.doCommand(key, (k, jedis) -> jedis.ttl(k), isFullKey);
        return ttlValue;
    }
    
    static {
        log = LoggerFactory.getLogger((Class)RedisOperater.class);
    }
    
    @FunctionalInterface
    interface RedisCallback<T>
    {
        T callback(final byte[] p0, final RedisBinaryCommand p1) throws Exception;
    }
}
